import 'package:flutter/widgets.dart';

import 'index.dart';

class CommonNavigatorObserver extends NavigatorObserver {
  CommonNavigatorObserver._();

  static final CommonNavigatorObserver _instance = CommonNavigatorObserver._();

  factory CommonNavigatorObserver() => _instance;

  final _popCallback = <String, VoidCallback>{};
  final _leaveHideCallback = <String, VoidCallback>{};
  final _backShowCallback = <String, VoidCallback>{};

  String _getKey(String pageName) {
    if (pageName.startsWith('/')) return pageName;
    return '/$pageName';
  }

  ///监听某页关闭了,(一般用于[pageName]页监听关闭触发 设置返回值,只生效一次，不需手动移除)
  void listenPop(String pageName, VoidCallback callback) {
    Log.log('CommonNavigatorObserver listenPop : $pageName');
    _popCallback[_getKey(pageName)] = callback;
  }

  ///监听某页不显示了（一般用于[pageName]页监听，[leave]暂停耗时操作,[back]重启耗时操作）
  void listenLeaveOrBack(String pageName, {VoidCallback? leave, VoidCallback? back}) {
    String key = _getKey(pageName);
    Log.log('CommonNavigatorObserver listenLeaveOrBack : $key');
    if (leave != null) _leaveHideCallback[key] = leave;
    if (back != null) _backShowCallback[key] = back;
  }

  ///移除一个[pageName]的监听（[listenLeaveHide]与[listenBackShow]中的）
  void removeLeaveOrBack(String pageName) {
    String key = _getKey(pageName);
    Log.log('CommonNavigatorObserver listenLeaveOrBack : $key');
    if (_leaveHideCallback.containsKey(key)) {
      _leaveHideCallback.remove(key);
    }
    if (_backShowCallback.containsKey(key)) {
      _backShowCallback.remove(key);
    }
  }

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    String name = route.settings.name ?? '';
    String previousName = previousRoute?.settings.name ?? "";
    Log.log("CommonNavigatorObserver didPush : $name , previousRoute = $previousName");
    String key = _getKey(previousName);
    bool contains = _leaveHideCallback.containsKey(key);
    Log.log("CommonNavigatorObserver didPush _leaveHideCallback has key : "
        "$contains, key = $key");
    if (contains && name.isNotEmpty) {
      _leaveHideCallback[key]!.call();
    }
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    String name = route.settings.name ?? '';
    String previousName = previousRoute?.settings.name ?? "";
    Log.log("CommonNavigatorObserver didPop : $name , previousRoute = $previousName");
    String key1 = _getKey(name);
    if (_popCallback.containsKey(key1)) {
      _popCallback[key1]!.call();
      _popCallback.remove(key1);
    }
    String key = _getKey(previousName);
    bool contains = _backShowCallback.containsKey(key);
    Log.log("CommonNavigatorObserver didPop _backShowCallback has key : "
        "$contains, key = $key");
    if (contains && name.isNotEmpty) {
      _backShowCallback[key]!.call();
    }
  }

  @override
  void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {}

  @override
  void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {}

  @override
  void didStartUserGesture(Route<dynamic> route, Route<dynamic>? previousRoute) {}

  @override
  void didStopUserGesture() {}

  void debugPrint() {
    _popCallback.keys.forEach((element) {
      Log.log('_popCallback : k = $element , v = ${_popCallback[element]}');
    });
    _leaveHideCallback.keys.forEach((element) {
      Log.log('_leaveHideCallback : k = $element , v = ${_leaveHideCallback[element]}');
    });
    _backShowCallback.keys.forEach((element) {
      Log.log('_backShowCallback : k = $element , v = ${_backShowCallback[element]}');
    });
  }
}
